#include "widget.h"

#include <QDebug>
//光照参数
GLfloat lightAmbient[]={0.5,0.5,0.5,1};
GLfloat lightdiffuse[]={1,1,1,1};
GLfloat lightPos[]={0,0,1,1};

bool masking=false;
bool scene= false;
Widget::Widget(QWidget *parent) :
    QGLWidget(parent)
{
    setGeometry(200,200,600,600);
    mMove_z=-0.8;
    mRotate_x=mRotate_y=mRotate_z=0;
}

Widget::~Widget()
{
}


void Widget::initializeGL()
{
    //纹理
    glGenTextures(5,mTexture);

    LoadGLTextures("G:\\Project\\LearningOpenGL\\test20_mask\\Data\\Image1.bmp",mTexture[0]);
    LoadGLTextures("G:\\Project\\LearningOpenGL\\test20_mask\\Data\\Image2.bmp",mTexture[1]);
    LoadGLTextures("G:\\Project\\LearningOpenGL\\test20_mask\\Data\\Logo.bmp",mTexture[2]);
    LoadGLTextures("G:\\Project\\LearningOpenGL\\test20_mask\\Data\\Mask1.bmp",mTexture[3]);
    LoadGLTextures("G:\\Project\\LearningOpenGL\\test20_mask\\Data\\Mask2.bmp",mTexture[4]);

    glEnable(GL_TEXTURE_2D);
    //阴影
    glShadeModel(GL_SMOOTH);         //shade model

    glClearColor(1,1,1,0.5);   //clear color depth

    glClearDepth(1.0);


    //禁止深度检测
    glEnable(GL_DEPTH_TEST);        //enable depth
    //glDepthFunc(GL_LEQUAL);         //depth func

    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST); //perspective hint

    //光照
    //LightInit();
    //混合
    //BlendInit();

    //剔除表面
    //glEnable(GL_CULL_FACE);


}

void Widget::resizeGL(int w, int h)
{
    glViewport(0,0,(GLint)w,(GLint)h);     //viewport
    //glMatrixMode(GL_PROJECTION);            //matrix mode
    //glLoadIdentity();                       //reset

    glMatrixMode(GL_PROJECTION);
    glFrustum(-1.5,1.5,-(float)h/w*1.5,(float)h/w*1.5,0.5,5);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}
void Widget::DrawMask(float x,float y,float z,float roll)
{
    glBindTexture(GL_TEXTURE_2D,mTexture[1]);
    glTranslatef(0.0f,0.0f,-1.0f);
    glBegin(GL_QUADS);					// 开始绘制四边形

    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.1f, -1.1f,  0.0f);

    glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.1f, -1.1f,  0.0f);

    glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.1f,  1.1f,  0.0f);

    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.1f,  1.1f,  0.0f);

    glEnd();
}

void Widget::DrawCubic(float x,float y,float z,float roll)
{

    glBindTexture(GL_TEXTURE_2D,mTexture[0]);
    glBegin(GL_QUADS);
    glTexCoord2f(0+roll,0); glVertex3f(x-1,y-1,z);
    glTexCoord2f(1+roll,0);glVertex3f(x+1,y-1,z);
    glTexCoord2f(1+roll,1);glVertex3f(x+1,y+1,z);
    glTexCoord2f(0+roll,1);glVertex3f(x-1,y+1,z);
    glEnd();
}

void Widget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);   //clear
    glLoadIdentity();
    glTranslatef(0,0,mMove_z);
    glRotatef(mRotate_x,1,0,0);
    glRotatef(mRotate_y,0,1,0);
    glRotatef(mRotate_z,0,0,1);
    float x,y,z;
    x=y=z=0;
    float roll=0.5;


    glBindTexture(GL_TEXTURE_2D,mTexture[0]);
    glBegin(GL_QUADS);							// 绘制纹理四边形
        glTexCoord2f(0.0f, -roll+0.0f); glVertex3f(-1.1f, -1.1f,  0.0f);
        glTexCoord2f(3.0f, -roll+0.0f); glVertex3f( 1.1f, -1.1f,  0.0f);
        glTexCoord2f(3.0f, -roll+3.0f); glVertex3f( 1.1f,  1.1f,  0.0f);
        glTexCoord2f(0.0f, -roll+3.0f); glVertex3f(-1.1f,  1.1f,  0.0f);
    glEnd();

    glEnable(GL_BLEND);							// 启用混合
    glDisable(GL_DEPTH_TEST);							// 禁用深度测试

    if(masking)
        glBlendFunc(GL_DST_COLOR,GL_ZERO);
    else
        qDebug()<<"not mask";
    if(scene)
    {
        glTranslatef(0.0f,0.0f,-1.0f);					// 移入屏幕一个单位
        if(masking)
        {
            qDebug()<<"Drawing mask3";
            glBindTexture(GL_TEXTURE_2D,mTexture[3]);
            glBegin(GL_QUADS);
                glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.1f, -1.1f,  0.0f);
                glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.1f, -1.1f,  0.0f);
                glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.1f,  1.1f,  0.0f);
                glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.1f,  1.1f,  0.0f);
            glEnd();
        }

        glBlendFunc(GL_ONE, GL_ONE);					// 把纹理1复制到屏幕
        glBindTexture(GL_TEXTURE_2D, mTexture[4]);				// 选择第一个纹理
        glBegin(GL_QUADS);							// 开始绘制四边形
        glTexCoord2f(roll+0.0f, 0.0f); glVertex3f(-1.1f, -1.1f,  0.0f);
        glTexCoord2f(roll+4.0f, 0.0f); glVertex3f( 1.1f, -1.1f,  0.0f);
        glTexCoord2f(roll+4.0f, 4.0f); glVertex3f( 1.1f,  1.1f,  0.0f);
        glTexCoord2f(roll+0.0f, 4.0f); glVertex3f(-1.1f,  1.1f,  0.0f);
        glEnd();

    }
    else
    {
        if (masking)									// Is Masking On?
        {
            glBindTexture(GL_TEXTURE_2D, mTexture[1]);	// Select The First Mask Texture
            glBegin(GL_QUADS);							// Start Drawing A Textured Quad
            glTexCoord2f(roll+0.0f, 0.0f); glVertex3f(-1.1f, -1.1f,  0.0f);	// Bottom Left
            glTexCoord2f(roll+4.0f, 0.0f); glVertex3f( 1.1f, -1.1f,  0.0f);	// Bottom Right
            glTexCoord2f(roll+4.0f, 4.0f); glVertex3f( 1.1f,  1.1f,  0.0f);	// Top Right
            glTexCoord2f(roll+0.0f, 4.0f); glVertex3f(-1.1f,  1.1f,  0.0f);	// Top Left
            glEnd();									// Done Drawing The Quad
        }

        glBlendFunc(GL_ONE, GL_ONE);					// Copy Image 1 Color To The Screen
        glBindTexture(GL_TEXTURE_2D, mTexture[2]);		// Select The First Image Texture
        glBegin(GL_QUADS);								// Start Drawing A Textured Quad
        glTexCoord2f(roll+0.0f, 0.0f); glVertex3f(-1.1f, -1.1f,  0.0f);	// Bottom Left
        glTexCoord2f(roll+4.0f, 0.0f); glVertex3f( 1.1f, -1.1f,  0.0f);	// Bottom Right
        glTexCoord2f(roll+4.0f, 4.0f); glVertex3f( 1.1f,  1.1f,  0.0f);	// Top Right
        glTexCoord2f(roll+0.0f, 4.0f); glVertex3f(-1.1f,  1.1f,  0.0f);	// Top Left
        glEnd();										// Done Drawing The Quad
    }
    glEnable(GL_DEPTH_TEST);							// 启用深度测试
    glDisable(GL_BLEND);							// 禁用混合
    //DrawMask(x,y,z,roll);
}
void Widget::keyPressEvent(QKeyEvent* e)
{
    switch(e->key())
    {
    case Qt::Key_Left:
        mRotate_z-=10;
        break;
    case Qt::Key_Right:
        mRotate_z+=10;
        break;
    case Qt::Key_Up:
        mRotate_x-=10;
        break;
    case Qt::Key_Down:
        mRotate_x+=10;
        break;
    case Qt::Key_Plus:
        mMove_z+=1;
        break;
    case Qt::Key_Minus:
        mMove_z-=1;
        break;

    case Qt::Key_L:
    {
        GLboolean light;
        glGetBooleanv(GL_LIGHTING,&light);
        light=!light;
        if(light)
            glEnable(GL_LIGHTING);
        else
            glDisable(GL_LIGHTING);
        break;
    }

    case Qt::Key_M:
    {
        qDebug()<<"Masking";
        masking=!masking;
        break;
    }
    case Qt::Key_S:
    {
        qDebug()<<"Masking";
        scene=!scene;
        break;
    }
    case Qt::Key_B:
    {
        GLboolean blend;
        glGetBooleanv(GL_BLEND,&blend);
        blend=!blend;
        if(blend)
        {
            glEnable(GL_BLEND);
            glDisable(GL_DEPTH_TEST);
        }
        else
        {
            glDisable(GL_BLEND);
            glEnable(GL_DEPTH_TEST);
        }
    }
    }
    updateGL();
}


void Widget::LoadGLTextures(QString filename,GLuint textureid)
{
    QImage image(filename);
    if(image.isNull())
    {
        qDebug()<<"Image Is Null";
        return;
    }
    else
        qDebug()<<"w:"<<image.width();
    QImage Tex=QGLWidget::convertToGLFormat(image);

    glBindTexture(GL_TEXTURE_2D,textureid);
    glTexImage2D(GL_TEXTURE_2D,0,3,image.width(),image.height(),0,GL_RGBA,GL_UNSIGNED_BYTE,Tex.bits());
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
}
void Widget::LightInit()
{
    //光照
    glLightfv(GL_LIGHT1,GL_AMBIENT,lightAmbient);
    glLightfv(GL_LIGHT1,GL_DIFFUSE,lightdiffuse);
    glLightfv(GL_LIGHT1,GL_POSITION,lightPos);
    glEnable(GL_LIGHT1);
}
void Widget::BlendInit()
{
    //glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    glColor4f(1,1,1,0.5);
    //在深度缓存启用时，您应该将透明图形按照深度进行排序，并在全部场景绘制完毕之后再绘制这些透明物体。否则您将得到不正确的结果。我知道某些时候这样做是很令人痛苦的，但这是正确的方法。
    glBlendFunc(GL_DST_COLOR,GL_ZERO);

}
